﻿#region using statements

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

#endregion

namespace NGen.Managers.GameObject
{
	/// <summary>
	/// 	delegate the reference type for which object events can be created
	/// </summary>
	/// <param name = "p_gameObject">the game object</param>
	public delegate void ObjectListener(GameObject p_gameObject);

	/// <summary>
	/// 	base gameobject class which defines the behavior of game objects which
	/// 	can be managed by the manager
	/// </summary>
	public abstract class GameObject
	{
		#region local events

		/// <summary>
		/// 	event which gets thrown whenever this objects gets detroyed
		/// </summary>
		protected event ObjectListener ObjectDestroyedEvent;

		#endregion

		#region properties

		/// <summary>
		/// 	get this objects unique identifier
		/// </summary>
		public uint Id { get; internal set; }

		/// <summary>
		/// 	should this objects' update call be skipped
		/// </summary>
		public bool SkipUpdate { get; set; }

		/// <summary>
		/// 	should this objects' draw call be skipped
		/// </summary>
		public bool SkipDraw { get; set; }

		/// <summary>
		///		subscribe or unsubscribe from notifications when this object is destroyed
		/// </summary>
		public event ObjectListener OnObjectDestroyedEvent {
			add { ObjectDestroyedEvent += value; }
			remove { ObjectDestroyedEvent -= value; }
		}

		#endregion

		#region local methods

		/// <summary>
		/// 	initialize the game object
		/// </summary>
		protected internal virtual void _Initialize() {}

		/// <summary>
		/// 	update the game object
		/// </summary>
		/// <param name = "p_gameTime">snapshot of timing values</param>
		protected internal virtual void _Update(GameTime p_gameTime) {}

		/// <summary>
		/// 	draw the game object
		/// </summary>
		/// <param name = "p_gameTime">snapshot of timing values</param>
		protected internal virtual void _Draw(GameTime p_gameTime) {}

		/// <summary>
		/// 	cleanup the game object
		/// </summary>
		protected internal virtual void _Cleanup() {}

		#endregion

		#region static methods

		/// <summary>
		/// 	shortcut to the object manager to destroy this object
		/// </summary>
		public static void Destroy(uint p_objectId) {
			GameEngine.GetService<IManagerGameObjects>().DestroyGameObjectById(p_objectId);
		}

		/// <summary>
		/// 	notify any object listeners when this objects gets destroyed
		/// </summary>
		public static void ThrowObjectDestroyedEvent(GameObject p_object) {
			if(p_object.ObjectDestroyedEvent != null) {
				p_object.ObjectDestroyedEvent(p_object);
			}
		}

		#endregion
	}
}